#include <stdint.h>
#include <stdio.h>
//#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>
#include "stm32f1xx_hal.h"
#include "esp8266.h"

void esp8266_printf(esp8266_t*p,char* fmt,...) 
{
	va_list ap;
	va_start(ap,fmt);
	vsprintf(p->tbuff,fmt,ap);
	va_end(ap);
	p->tlen = strlen(p->tbuff);
}


void esp8266_resetio(bool bStatus)
{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,bStatus ? GPIO_PIN_SET:GPIO_PIN_RESET);
}
int32_t esp8266_send(char*buf,uint16_t len,uint32_t timeout)
{
    extern UART_HandleTypeDef huart2;
    return HAL_UART_Transmit(&huart2,(uint8_t*)buf,len,timeout);
}
int32_t esp8266_recv(char*buf,uint16_t len)
{
//    extern UART_HandleTypeDef huart2;
//    return HAL_UART_Receive_DMA(&huart2,(uint8_t*)buf,len);
return 0;
}

int32_t esp8266_sendcmd(esp8266_t*p,char* cmd,uint32_t timeout)
{
    extern UART_HandleTypeDef huart2;
    uint16_t rlen;
    p->rlen = 0;
    memset(p->rbuff,0,sizeof(p->rbuff));
    esp8266_printf(p,"%s\r\n",cmd);
    if( 0 != esp8266_send(p->tbuff,p->tlen,timeout))
        return -1;
    if( 0 != esp8266_recv(p->rbuff,sizeof(p->rbuff)))
        return -2;
    while(1)
    {
        rlen = sizeof(p->rbuff) - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        HAL_Delay(1);
        if(rlen > 0 && rlen == p->rlen)
            break;
        p->rlen = rlen;
        timeout--;
        if(0 == timeout)
            return -3;
    }
    if(strstr(p->rbuff,"OK"))
        return 0;
    else
        return -4;
}

int32_t esp8266_init(esp8266_t*p,uint32_t timeout)
{
    memset(p,0,sizeof(esp8266_t));
    return 0;
}
int32_t esp8266_reset(esp8266_t*p,uint32_t timeout)
{
    extern UART_HandleTypeDef huart2;
    uint16_t rlen;
    esp8266_resetio(false);
    HAL_Delay(500);
    esp8266_resetio(true);
    
    p->rlen = sizeof(p->rbuff);
    if( 0 != esp8266_recv(p->rbuff,sizeof(p->rbuff)))
        return -1;
    while(1)
    {
        HAL_Delay(1);
        rlen = sizeof(p->rbuff) - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        if(rlen > 4 && rlen == p->rlen)
            break;
        p->rlen = rlen;
        timeout--;
        if(0 == timeout)
            return -2;
    }
    if(strstr(p->rbuff,"WIFI"))
        return 0;
    else
        return -3;
}

int32_t esp8266_joinap(esp8266_t*p,int timeout)
{
    extern UART_HandleTypeDef huart2;
    uint16_t rlen;
    memset(p->rbuff,0,sizeof(p->rbuff));
    esp8266_printf(p,"AT+CWJAP=\"%s\",\"%s\"\r\n",p->SSID,p->PASSWD);
    if( 0 != esp8266_send(p->tbuff,p->tlen,timeout))
        return -1;
    p->rlen = sizeof(p->rbuff);
    if( 0 != esp8266_recv(p->rbuff,sizeof(p->rbuff)))
        return -2;
    while(1)
    {
        HAL_Delay(1);
        rlen = sizeof(p->rbuff) - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        if(rlen > 10 && rlen == p->rlen)
            break;
        p->rlen = rlen;
        timeout--;
        if(0 == timeout)
            return -3;
    }
    if(strstr(p->rbuff,"WIFI GOT IP\r\n\r\nOK"))
        return 0;
    else
        return -4;
}


int32_t esp8266_connect_server(esp8266_t*p,uint32_t timeout)
{
    extern UART_HandleTypeDef huart2;
    uint16_t rlen;
    p->rlen = 0;
    memset(p->rbuff,0,sizeof(p->rbuff));
    esp8266_printf(p,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",p->ServerIP,p->ServerPort);
    
    if( 0 != esp8266_send(p->tbuff,p->tlen,timeout))
        return -1;
    if( 0 != esp8266_recv(p->rbuff,sizeof(p->rbuff)))
        return -2;
    while(1)
    {
        rlen = sizeof(p->rbuff) - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        HAL_Delay(5);
        if(rlen > 0 && rlen == p->rlen)
            break;
        p->rlen = rlen;
        timeout--;
        if(0 == timeout)
            return -3;
    }
    if(strstr(p->rbuff,"OK"))
        return 0;
    else
        return -4;
}

int32_t esp8266_waitap(esp8266_t*p,uint32_t timeout)
{
    extern UART_HandleTypeDef huart2;
    uint16_t rlen;
    while(1)
    {
        rlen = sizeof(p->rbuff) - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
        HAL_Delay(100);
        if(rlen > 0 && rlen == p->rlen)
            break;
        p->rlen = rlen;
        timeout--;
        if(0 == timeout)
            return -1;
    }
    if(strstr(p->rbuff,"WIFI GOT IP"))
        return 0;
    else
        return -2;
}

int32_t esp8266_connect_modbusserver(esp8266_t*p,uint32_t timeout)
{
    p->ret = esp8266_reset(p,timeout);
    HAL_Delay(1000);
    p->ret = esp8266_sendcmd(p,"AT+CWMODE=1",500);
    HAL_Delay(1000);
    p->ret = esp8266_sendcmd(p,"AT+CWAUTOCONN=0",500);
    HAL_Delay(1000);
    p->ret = esp8266_joinap(p,500);
    HAL_Delay(1000);
    p->ret = esp8266_sendcmd(p,"AT+CIPMODE=1",500);
    HAL_Delay(1000);
    p->ret = esp8266_sendcmd(p,"AT+CIPMUX=0",500);
    HAL_Delay(1000);
    p->ret = esp8266_connect_server(p,100);
    HAL_Delay(1000);
    return 0;
}



